package com.example.hospital.api.service.impl;

import cn.hutool.core.annotation.Link;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.example.hospital.api.db.dao.DoctorWorkPlanDao;
import com.example.hospital.api.db.pojo.DoctorWorkPlanEntity;
import com.example.hospital.api.db.pojo.DoctorWorkPlanScheduleEntity;
import com.example.hospital.api.exception.HospitalException;
import com.example.hospital.api.service.DoctorWorkPlanScheduleService;
import com.example.hospital.api.service.MedicalDeptSubWorkPlanService;
import com.sun.jersey.spi.container.ResourceFilters;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author Baiken
 * @version 1.0
 * @description: 封装出诊计划
 * @date 2024/9/9 下午6:22
 */
@Service
public class MedicalDeptSubWorkPlanServiceImpl implements MedicalDeptSubWorkPlanService {

    @Resource
    private DoctorWorkPlanDao doctorWorkPlanDao;

    @Resource
    private DoctorWorkPlanScheduleService doctorWorkPlanScheduleService;


    @Override
    public JSONArray searchWorkPlanInRange(Map param, ArrayList dataList) {
        ArrayList<HashMap> list = doctorWorkPlanDao.searchWorkPlanInRange(param);
        Integer tempSubId = null;
        String tempDate = null;
        HashMap tempResult = new HashMap();
        for(HashMap one : list){
            String deptName = MapUtil.getStr(one,"deptName");
            String deptSubName = MapUtil.getStr(one,"deptSubName");
            String doctorName = MapUtil.getStr(one,"doctorName");
            String date = MapUtil.getStr(one,"date");
            int deptSubId = MapUtil.getInt(one,"deptSubId");
            int workPlanId = MapUtil.getInt(one,"workPlanId");

            //判断是否是第一条记录
            if(tempSubId == null){
                tempSubId = deptSubId;
                tempDate = date;
                //把第一条记录当作一个诊室
                HashMap temp = new HashMap(){{
                    put("deptName",deptName);
                    put("deptSubId",deptSubId);
                    put("deptSubName",deptSubName);
                    /*诊室出诊计划
                    用linkedHashMap,确保顺序不会被打乱
                    * */
                    put("plan",new LinkedHashMap<>(){{
                        put(date,new ArrayList<>(){{
                            add(doctorName);
                        }});
                    }});
                }};
                tempResult.put(deptSubId,temp);
                //不是第一条记录,但与前一条同诊室,且同一天
            } else if (tempSubId == deptSubId && tempDate.equals(date)) {
                //取出诊室
                HashMap map = (HashMap) tempResult.get(deptSubId);
                //取出诊室出诊计划
                LinkedHashMap plan = (LinkedHashMap) map.get("plan");
                //取出诊室出诊计划中的医生名单
                ArrayList doctors = (ArrayList) plan.get(date);
                //添加这名医生
                doctors.add(doctorName);
            }
            //同诊室,不同天
            else if(tempSubId == deptSubId && !tempDate.equals(date)){
                tempDate = date;
                HashMap map = (HashMap) tempResult.get(deptSubId);
                LinkedHashMap plan = (LinkedHashMap)map.get("plan");
                plan.put(date,new ArrayList<>(){{
                    add(doctorName);
                }});
            }
            //诊室不同
            else if (tempSubId != deptSubId) {
                tempSubId = deptSubId;
                tempDate = date;
                HashMap temp = new HashMap<>(){{
                    put("deptName",deptName);
                    put("deptSubId",deptSubId);
                    put("deptSubName",deptSubName);
                    put("plan",new LinkedHashMap<>(){{
                        put(date,new ArrayList<>(){{
                            add(doctorName);
                        }});
                    }});
                }};
                tempResult.put(deptSubId,temp);
            }
        }
        //确保每天都有出诊,没有医生传入一个空ArrayList
        Set<Map.Entry> set = tempResult.entrySet();
        set.forEach(one -> {
            HashMap map = (HashMap) one.getValue();
            LinkedHashMap plan = (LinkedHashMap) map.get("plan");
            dataList.forEach(date->{
                if(!plan.containsKey(date)){
                    plan.put(date,new ArrayList<>());
                }
            });
            TreeMap sort = MapUtil.sort(plan,new Comparator(){
                @Override
                public int compare(Object o1, Object o2){
                    String key1 = (String) o1;
                    String key2 = (String) o2;
                    boolean bool = new DateTime(key1).isAfter(new DateTime(key2));
                    return bool ? 1 : -1;
                }
            });
            map.replace("plan",sort);
        });
        Collection<HashMap> values = tempResult.values();
        values.forEach(one -> {
            TreeMap plan = (TreeMap)one.get("plan");
            Set<Map.Entry> tempSet = plan.entrySet();
            ArrayList temp = new ArrayList<>();
            tempSet.forEach(entry -> {
                temp.add(new HashMap<>(){{
                    put("date",entry.getKey());
                    put("doctors",entry.getValue());
                }});
            });
            one.replace("plan",temp);
        });
        return JSONUtil.parseArray(values);
    }

    @Override
    public String insert(Map param) {
        System.out.println("**********************************************************");
        System.out.println(param);
        Integer id = doctorWorkPlanDao.searchId(param);
        if(id != null){
            return "已近存在出诊计划,无法重复添加";
        }
        DoctorWorkPlanEntity entity_1 = BeanUtil.toBean(param,DoctorWorkPlanEntity.class);
        int totalMaximum=MapUtil.getInt(param,"totalMaximum");
        entity_1.setMaximum(totalMaximum);
        System.out.println("******************************************************************");
        System.out.println(entity_1);
        doctorWorkPlanDao.insert(entity_1);
        id = doctorWorkPlanDao.searchId(param);
        Integer[] slots = (Integer[])param.get("slots");
        ArrayList<DoctorWorkPlanScheduleEntity> list = new ArrayList<>();
        for(Integer slot : slots){
            DoctorWorkPlanScheduleEntity entity_2 = BeanUtil.toBean(param,DoctorWorkPlanScheduleEntity.class);
            Integer slotMaximum = MapUtil.getInt(param, "slotMaximum");
            entity_2.setWorkPlanId(id);
            entity_2.setSlot(slot);
            entity_2.setMaximum(slotMaximum);
            list.add(entity_2);
        }
        doctorWorkPlanScheduleService.insert(list);
        return "success";
    }

    @Override
    @Transactional
    public void deleteWorkPlan(int workPlanId) {
        Integer num = doctorWorkPlanDao.searchNumById(workPlanId);
        if(num > 0 ){
            throw new HospitalException("已经有患者挂号禁止删除");
        }
        doctorWorkPlanDao.deleteById(workPlanId);
        doctorWorkPlanScheduleService.deleteByWorkPlanId(workPlanId);
    }
}
